#include <gtest/gtest.h>
#include <lcir/ADT/IList.h>
#include <lcir/ADT/ListNode.h>
#include <lcir/ADT/Range.h>
#include <dialects/Builtin/Builtin.h>
#include <dialects/Func/Func.h>
#include <dialects/PL/PL.h>
#include <lcir/IR/Argument.h>
#include <lcir/IR/Constant.h>
#include <lcir/IR/Context.h>
#include <lcir/IR/ExprTemps.h>
#include <lcir/IR/Expression.h>
#include <lcir/IR/IRBuilder.h>
#include <lcir/IR/IRRewritter.h>
#include <lcir/IR/Lambda.h>
#include <lcir/IR/LambdaProto.h>
#include <lcir/IR/LambdaType.h>
#include <lcir/IR/Op.h>
#include <lcir/IR/Prototype.h>
#include <lcir/IR/Slot.h>
#include <lcir/IR/SlotCombiner.h>
#include <lcir/IR/Type.h>
#include <lcir/IR/VReg.h>
#include <lcir/IR/ValuePrinter.h>

#include <iterator>
#include <memory>
#include <string>
#include <vector>
using namespace lcir;
using namespace lcir::pl;
using namespace lcir::func;
class Exprs : public testing::Test {
 protected:
  void SetUp() override {
    // 初始化lambda
    module = Lambda::get();
    IRBuilder builder(module);
    builder.setInsertPoint(module);
    auto *x = builder.createAndGetRet<DeclVar>(Int32Type::get(), "x");
    auto *y = builder.createAndGetRet<DeclVar>(Int32Type::get(), "y");
    auto *z = builder.createAndGetRet<DeclVar>(Int32Type::get(), "z");
    add1 = builder.createAndGetRet<pl::Add>({x, y});
    add2 = builder.createAndGetRet<pl::Add>({x, z});
    mul = builder.createAndGetRet<Mul>({add1, add2});
    ret = builder.create<Return>({mul});
  }

  Lambda *module{nullptr};
  Value *add1{nullptr};
  Value *add2{nullptr};
  Value *mul{nullptr};
  Expression *ret{nullptr};
};
TEST_F(Exprs, remove) {
  std::cout << "before:\n";
  std::cout << module->print() << std::endl;
  auto ret = module->removeFromLambda(add1->getDefExpr(), mul->getDefExpr());
  std::cout << "after:\n";
  module->walkOnOp<DeclVar>([](Expression *expr) {
    expr->dump();
    // return walkInterrupt();
  });
}
